﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Collections;
using Microsoft.Win32;

namespace ehost
{
    public partial class mainForm : Form
    {

        public Dictionary<int, Host> change = new Dictionary<int, Host>();
        public List<Host> newHost = new List<Host>();
        public List<int> delete = new List<int>();
        public mainForm()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            readHosts();  
        }

        public void disableSaveHostButton()
        {
            SaveHostButton.Enabled = false;
        }

        public void useSaveHostButton()
        {
            SaveHostButton.Enabled = true;
           
        }

        public void addChange(int key, Host value)
        {
            if (change.ContainsKey(key))
            {
                change.Remove(key);
            }
            change.Add(key, value);
            useSaveHostButton();
        }
        public void addNewHost(Host host)
        {
            newHost.Add(host);
            useSaveHostButton();
        }

        public void addDeleteHost(int lineNum)
        {
            delete.Add(lineNum);
            useSaveHostButton();
        }

        private void Clear()
        {
            newHost.Clear();
            delete.Clear();
            change.Clear();
        }
      
        //读取host，生成TreeView
        private void readHosts()
        {
            Clear();

            StreamReader sr = new StreamReader("C:\\WINDOWS\\system32\\drivers\\etc\\HOSTS");

            Dictionary<String, List<Host>> dic = new Dictionary<string, List<Host>>();

            String line = sr.ReadLine();

            int lineNum = 1;

            while (line != null)
            {
                Host host = Utils.toHost(line);
             
                line = sr.ReadLine();

                if (host == null)
                {
                    lineNum++;
                    continue;
                }

                host.lineNum = lineNum;

                List<Host> array = null;
                if (dic.TryGetValue(host.domain, out array))
                {
                    array.Add(host);
                }
                else
                {
                    array = new List<Host>();
                    array.Add(host);
                    dic.Add(host.domain,array);
                }

                lineNum++;
               

            }
            sr.Close();

            mainTree.Nodes.Clear();
            foreach (String key in dic.Keys)
            {
                TreeNode node = new TreeNode();
                node.Text=key;

                List<Host> array=null;
                if (dic.TryGetValue(key, out array))
                {
                    foreach (Host host in array)
                    {
                        TreeNode temp = new TreeNode();

                        temp.Tag = host;
                        temp.Text = host.ip;

                        if (!String.IsNullOrEmpty(host.comment))
                        {
         
                            temp.Text = temp.Text + "  (" + host.comment+")";
                        }

                        if (host.able)
                        {
                            temp.Checked = true;
                            node.Checked = true;
                        }
                        node.Nodes.Add(temp);
                    }
                }
                mainTree.Nodes.Add(node);
            }
            disableSaveHostButton();
        }

        private void writeHost()
        {
            StreamReader sr = new StreamReader("C:\\WINDOWS\\system32\\drivers\\etc\\HOSTS");

            FileStream file = new FileStream("C:\\WINDOWS\\system32\\drivers\\etc\\HOSTS_TEMP", FileMode.Create);
            StreamWriter sw = new StreamWriter(file);

            String line = "";

            int lineNum = 1;

            Host host=null;

            while (line != null)
            {
              
                line = sr.ReadLine();
                if (String.IsNullOrEmpty(line))
                {
                    lineNum++;
                    continue;
                }


                if (delete.Contains(lineNum))
                {
                    lineNum++;
                    sw.WriteLine();
                    continue;
                }
                else if (change.TryGetValue(lineNum, out host))
                {
                    String hostStr = "";
                    if (host.able == false) hostStr += "#";

                    hostStr += host.ip + " " + host.domain;

                    if (!string.IsNullOrEmpty(host.comment)) hostStr += " #" + host.comment;

                    sw.WriteLine(hostStr);

                }
                else
                {
                    sw.WriteLine(line);
                }
                lineNum++;
            }

            foreach (Host h in newHost)
            {
                String hostStr = "";
                if (h.able == false) hostStr += "#";

                hostStr += h.ip + " " + h.domain;

                if (!string.IsNullOrEmpty(h.comment)) hostStr += " #" + h.comment;

                sw.WriteLine(hostStr);
            }


            sw.Flush();
            sw.Close();
            sr.Close();

            FileInfo form = new FileInfo("C:\\WINDOWS\\system32\\drivers\\etc\\HOSTS_TEMP");
            FileInfo to = new FileInfo("C:\\WINDOWS\\system32\\drivers\\etc\\HOSTS");
            copyFile(form, to);
            //清楚改变日志
          Clear();

           
            
        }

      
        private void copyFile(FileInfo form,FileInfo to)
        {
            if (to.Exists) to.Delete();

            File.Copy(form.FullName, to.FullName, true);
        }
       
        //节点右单击事件
        private void mainTree_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            //把选择的node换成鼠标按下的那个node
            mainTree.SelectedNode = e.Node;

            if (e.Button == MouseButtons.Right)
            {
                rightDown.Show(this, e.X, e.Y);
            }

            int level = e.Node.Level;

            if (level == 0)
            {
                addHost.Visible = true;
            }else if(level==1)
            {
                addHost.Visible = false;
            }

        }

        private void updateHost_Click(object sender, EventArgs e)
        {

            if (mainTree.SelectedNode.Level == 0)
            {
                Form updateHostForm = new updateHostForm(this);

                //相对于父窗口居中
                updateHostForm.StartPosition = FormStartPosition.CenterParent;

                updateHostForm.ShowDialog(this);
            }
            else if (mainTree.SelectedNode.Level == 1)
            {
                Form form = new UpdateIPFrom(this);
                form.StartPosition = FormStartPosition.CenterParent;
                form.ShowDialog(this);
            }

        }

        public TreeView getTreeView()
        {
            return this.mainTree;
        }

        private void addHost_Click(object sender, EventArgs e)
        {
            Form addHostForm = new AddHostForm(this,1);
            //相对于父窗口居中
            addHostForm.StartPosition = FormStartPosition.CenterParent;

            addHostForm.ShowDialog(this);
        }

        private void FlushButton_Click(object sender, EventArgs e)
        {
            readHosts();
        }

        private void AddHostButton_Click(object sender, EventArgs e)
        {
            Form addHostForm = new AddHostForm(this, 2);
            //相对于父窗口居中
            addHostForm.StartPosition = FormStartPosition.CenterParent;

            addHostForm.ShowDialog(this);
        }

        private void SaveHostButton_Click(object sender, EventArgs e)
        {
            writeHost();
            change.Clear();
            newHost.Clear();
            disableSaveHostButton();
        }

        private void deleteHost_Click(object sender, EventArgs e)
        {
            TreeNode tn = mainTree.SelectedNode;

            if (tn.Level == 0)
            {
                foreach (TreeNode t in tn.Nodes)
                {
                    addDeleteHost(((Host)t.Tag).lineNum);
                }
                
            }
            else if (tn.Level == 1)
            {
                addDeleteHost(((Host)tn.Tag).lineNum);

                if (tn.Parent.GetNodeCount(true) == 1)
                {
                    mainTree.Nodes.Remove(tn.Parent);
                }
            }

            mainTree.Nodes.Remove(tn);
        }

        private void mainTree_AfterCheck(object sender, TreeViewEventArgs e)
        {
            this.mainTree.AfterCheck -= new System.Windows.Forms.TreeViewEventHandler(this.mainTree_AfterCheck);

            if (e.Node.Level == 0)
            {
                e.Node.ExpandAll();
                foreach(TreeNode t in e.Node.Nodes)
                {
                    Host host = (Host)t.Tag;
                    host.able = e.Node.Checked;
                    t.Checked = e.Node.Checked;
                    addChange(host.lineNum, host);
                }
            }
            else if (e.Node.Level == 1)
            {
                Host host=(Host)e.Node.Tag;
                host.able = e.Node.Checked;
                addChange(host.lineNum, host);

                int checkCount = 0;
                foreach (TreeNode t in e.Node.Parent.Nodes)
                {
                    if (t.Checked==e.Node.Checked) checkCount++;
                }

                if (checkCount ==e.Node.Parent.GetNodeCount(true))
                {
                    e.Node.Parent.Checked = e.Node.Checked;
                }

                if (e.Node.Checked)
                {
                    e.Node.Parent.Checked = e.Node.Checked;
                }
            }

            this.mainTree.AfterCheck += new System.Windows.Forms.TreeViewEventHandler(this.mainTree_AfterCheck);

        }

        private void ToolsIEDNSUnuse_Click(object sender, EventArgs e)
        {
            RegistryKey key = Registry.CurrentUser;
            RegistryKey ss = key.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Internet Settings",true);
            ss.SetValue("DnsCacheEnabled", 00000000, RegistryValueKind.DWord);
            ss.SetValue("DnsCacheTimeout", 00000000, RegistryValueKind.DWord);
            ss.SetValue("ServerInfoTimeOut", 00000000, RegistryValueKind.DWord);
            ss.Close();
            key.Close();
        }

        private void ToolsIEDNSUse_Click(object sender, EventArgs e)
        {
            RegistryKey key = Registry.CurrentUser;
            RegistryKey ss = key.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Internet Settings",true);
            String[] array = ss.GetValueNames();
            if (array.Contains("DnsCacheEnabled")) ss.DeleteValue("DnsCacheEnabled");
            if (array.Contains("DnsCacheTimeout")) ss.DeleteValue("DnsCacheTimeout");
            if (array.Contains("ServerInfoTimeOut")) ss.DeleteValue("ServerInfoTimeOut");
            ss.Close();
            key.Close();
        }

        private void ClearIECacheMenu_Click(object sender, EventArgs e)
        {
            RegistryKey key = Registry.CurrentUser;
            RegistryKey ss = key.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Explorer\User shell folders", true);
            Object path =ss.GetValue("Cache");
            //FileUtils.deleteFile(Convert.ToString(path), false);
           
        }

    

       
    }
}
